/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package solitairetest;

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.image.*;

import solitairetest.logic.*;

/**
 *
 * @author Administrator
 */
public class KlondikeSuitPile extends Pile
{
    //public Deck pile;

    private int acceptableActions = DnDConstants.ACTION_MOVE;
    private DropTarget dropTarget;
    private DropTargetListener dropTargetListener;

    public KlondikeSuitPile(BufferedImage cards)
    {
        super();

        this.cards = cards;

        this.dropTargetListener = new PlayingPileDropTargetListener();
        this.dropTarget = new DropTarget(this,
                this.acceptableActions,
                this.dropTargetListener,
                true);
    }

    public KlondikeSuitPile(char suit, BufferedImage cards)
    {
        super();

        this.cards = cards;

        try
        {
            this.add(new CardCanvas(new Card(suit, 999, true), this.cards));
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }

        this.dropTargetListener = new PlayingPileDropTargetListener();
        this.dropTarget = new DropTarget(this,
                this.acceptableActions,
                this.dropTargetListener,
                true);
    }

    public java.awt.Component add(CardCanvas cc)
    {
        cc.pile = this;
        this.pileCards.add(cc);

        this.Redraw();

        return cc;
    }

    public void Redraw()
    {
        this.removeAll();

        for (int i = pileCards.size() - 1; i >= 0; i--)
        {
            this.pileCards.elementAt(i).setLocation(1, 1);
            this.add((Component)this.pileCards.elementAt(i));
        }
    }

    public void paint(Graphics g)
    {
        g.setColor(Color.gray);
        g.drawRect(0, 0, this.getWidth() - 1, this.getHeight() - 1);
    }

    public class PlayingPileDropTargetListener implements DropTargetListener
    {
        private boolean isDragFlavorSupported(DropTargetDragEvent e)
        {
            return e.isDataFlavorSupported(DeckTransferable.localCardFlavor) ||
                    e.isDataFlavorSupported(DeckTransferable.cardFlavor);
        }

        private DataFlavor chooseDropFlavor(DropTargetDropEvent e)
        {
            if (e.isDataFlavorSupported(DeckTransferable.localCardFlavor))
                return DeckTransferable.localCardFlavor;
            else if (e.isDataFlavorSupported(DeckTransferable.cardFlavor))
                return DeckTransferable.cardFlavor;

            return null;
        }

        private boolean isDragOk(DropTargetDragEvent e)
        {
            if(isDragFlavorSupported(e) == false)
            {
                System.out.println( "isDragOk:no flavors chosen" );
                return false;
            }

            int dropAction = e.getDropAction();
            System.out.print("dt drop action " + dropAction);
            System.out.println(" my acceptable actions " + acceptableActions);

            return (dropAction & KlondikeSuitPile.this.acceptableActions) != 0;
        }

        public void dragEnter(DropTargetDragEvent e)
        {
            System.out.println("PlayingPileDropTargetListener.dragEnter()");
            if (!isDragOk(e))
            {
                System.out.println("dragEnter not ok");
                e.rejectDrag();
            }
            else
            {
                System.out.println("dragEnter accepting: " + e.getDropAction());
                e.acceptDrag(e.getDropAction());
            }
        }

        public void dragOver(DropTargetDragEvent e)
        {
            System.out.println("PlayingPileDropTargetListener.dragOver()");
            if (!isDragOk(e))
            {
                System.out.println("dragOver not ok");
                e.rejectDrag();
            }
            else
            {
                System.out.println("dragOver accepting: " + e.getDropAction());
                e.acceptDrag(e.getDropAction());
            }
        }

        public void dropActionChanged(DropTargetDragEvent e)
        {
            System.out.println("PlayingPileDropTargetListener.dropActionChanged()");
            if (!isDragOk(e))
            {
                System.out.println("dropActionChanged not ok");
                e.rejectDrag();
            }
            else
            {
                System.out.println("dropActionChanged accepting: " + e.getDropAction());
                e.acceptDrag(e.getDropAction());
            }
        }

        public void dragExit(DropTargetEvent e)
        {
            System.out.println("PlayingPileDropTargetListener.dragExit()");
        }

        public void drop(DropTargetDropEvent e)
        {
            System.out.println("PlayingPileDropTargetListener.drop()");

            DataFlavor chosen = chooseDropFlavor(e);
            if (chosen == null)
            {
                System.err.println("No flavour match found");
                e.rejectDrop();
                return;
            }

            int dropAction = e.getDropAction();
            int sourceAction = e.getSourceActions();
            System.out.println("drop(), dropAction: " + dropAction);
            System.out.println("drop(), sourceAction: " + sourceAction);

            if ((sourceAction & KlondikeSuitPile.this.acceptableActions) == 0)
            {
                System.err.println("No action match found!");
                e.rejectDrop();
                return;
            }

            Object data = null;
            try
            {
                e.acceptDrop(KlondikeSuitPile.this.acceptableActions);

                data = e.getTransferable().getTransferData(chosen);
                if (data == null)
                    throw new NullPointerException();
            }
            catch (Throwable t)
            {
                System.err.println("Couldn't get transfer data: " + t.getMessage());
                t.printStackTrace();
                e.dropComplete(false);
                return;
            }
            System.out.println("Got data: " + data.getClass().getName());

            if (data instanceof Deck)
            {
                // LOGIC GOES HERE
                Deck deck = (Deck)data;

                if (deck.Size() == 1)
                {
                    Card c = deck.GetCard(0);
                    Card cAbove = KlondikeSuitPile.this.pileCards.lastElement().GetCard();
                    if (cAbove.GetSuit() == c.GetSuit())
                    {
                        if (cAbove.GetRank() + 1 == c.GetRank() || (cAbove.GetRank() == 999 && c.GetRank() == 1))
                        {
                            CardCanvas cc = new CardCanvas(c, cards);
                            cc.pile = KlondikeSuitPile.this;
                            KlondikeSuitPile.this.add(cc);
                        }
                        else
                        {
                            System.out.println("drop(), rejecting rank " + cAbove.GetRank() + ", " + c.GetRank());
                            e.dropComplete(false);
                            return;
                        }
                    }
                    else
                    {
                        System.out.println("drop(), rejecting suit");
                        e.dropComplete(false);
                        return;
                    }
                }
                else
                {
                    System.out.println("drop(), rejecting deck > 1");
                    e.dropComplete(false);
                    return;
                }
            }
            else
            {
                System.out.println("drop(), rejecting");
                e.dropComplete(false);
                return;
            }

            e.dropComplete(true);
        }
    }
}
